home *** CD-ROM | disk | FTP | other *** search
- %TITLE "Asynchronous Serial Communications Module"
-
- IDEAL
- DOSSEG
- MODEL small
-
- PUBLIC ComPort
-
- ComPort = 0
-
- IF ComPort EQ 0
- Port EQU 03F8h
- VectorNum EQU 0Ch
- EnableIRQ EQU 0EFh
- DisableIRQ EQU 10h
- ELSEIF ComPort EQ 1
- Port EQU 02F8h
- VectorNum EQU 0Bh
- EnableIRQ EQU 0F7h
- DisableIRQ EQU 08h
- ELSE
- %DISPLAY "ComPort must be 0 or 1"
- ERR
- ENDIF
-
- TxRegister = Port + 0
- RxRegister = Port + 0
- IntEnable = Port + 1
- IntIdent = Port + 2
- LineControl = Port + 3
- ModemControl = Port + 4
- LineStatus = Port + 5
- ModemStatus = Port + 6
-
- Ctrl8259_0 EQU 020h
- Ctrl8259_1 EQU 021h
- EOI EQU 020h
- BufSize EQU 2048
-
-
- DATASEG
-
- vectorSeg dw ?
- vectorOfs dw ?
- bufHead dw ?
- bufTail dw ?
- buffer db BufSize DUP (?)
-
- CODESEG
-
- PUBLIC AsynchInit, AsynchStop, AsynchStat
- PUBLIC AsynchOut, AsynchIn, AsynchInStat
-
- %NEWPAGE
- ;------------------------------------------------------------------------
- ; EmptyBuffer - empty the input buffer
- ;------------------------------------------------------------------------
- ; NOTE: private to module
- ; Input: none
- ; Output: none
- ; Registers: none
- ;------------------------------------------------------------------------
- PROC EmptyBuffer
- cli
- push ax
- mov ax, offset buffer
- mov [bufHead], ax
- mov [bufTail], ax
- pop ax
- sti
- ret
- ENDP EmptyBuffer
-
- %NEWPAGE
- ;------------------------------------------------------------------------
- ; AsynchInit - initialize serial port and install ISR
- ;------------------------------------------------------------------------
- ; Input: none
- ; Output: none
- ; NOTE: precede (usually) with call to int 14h
- ; to set baud rate
- ; NOTE: interrupt-driven input begins immediately
- ; upon exit from this routine
- ; WARNING: you MUST call AsynchStop before your program ends
- ; to avoid a !!! SYSTEM CRASH !!!
- ; Registers: ax,bx,dx
- ;------------------------------------------------------------------------
- PROC AsynchInit
- call EmptyBuffer
- push ds
- push es
- mov ax, 3500h + VectorNum
- int 21h
- mov [vectorSeg], es
- mov [vectorOfs], bx
- push cs
- pop ds
- mov ds, offset AsynchISR
- mov ax, 2500h + VectorNum
- int 21h
- pop es
- pop ds
- in al, Ctrl8259_1
- and al, EnableIRQ
- out Ctrl8259_1,al
- mov dx,LineControl
- in al,dx
- and al,07Fh
- out dx,al
- mov dx,IntEnable
- mov al,1
- out dx,al
- @@10:
- mov dx,RxRegister
- in al,dx
- mov dx,LineStatus
- in al,dx
- mov dx,ModemStatus
- in al,dx
- mov dx,IntIdent
- in al,dx
- test al,1
- jz @@10
- mov dx,ModemControl
- in al,dx
- or al,08h
- out dx,al
- call EmptyBuffer
- ret
- ENDP AsynchInit
-
- %NEWPAGE
- ;------------------------------------------------------------------------
- ; AsynchStop - uninstall asynch ISR
- ;------------------------------------------------------------------------
- ; Input: none
- ; Output: none
- ; WARNING: you MUST call AsynchStop before your program ends
- ; to avoid a !!! SYSTEM CRASH !!!
- ; Registers: al,dx
- ;------------------------------------------------------------------------
- PROC AsynchStop
- in al, Ctrl8259_1
- or al, DisableIRQ
- out Ctrl8259_1,al
- mov dx,LineControl
- in al,dx
- and al,07Fh
- out dx,al
- mov dx, IntEnable
- xor al,al
- out dx,al
- mov dx,ModemControl
- in al,dx
- and al, 0F7h
- out dx,al
- push ds
- mov ax, 2500h + VectorNum
- mov dx, [vectorOfs]
- mov ds,[vectorSeg]
- int 21h
- pop ds
- ret
- ENDP AsynchStop
-
- %NEWPAGE
- ;------------------------------------------------------------------------
- ; AsynchStat - get status for output
- ;------------------------------------------------------------------------
- ; Input: none
- ; Output: ah = line status, al = modem status
- ; Registers: ax,dx
- ;------------------------------------------------------------------------
- PROC AsynchStat
- mov ah,3
- mov dx, ComPort
- int 14h
- ret
- ENDP AsynchStat
-
- %NEWPAGE
- ;------------------------------------------------------------------------
- ; AsynchOut - output a byte (to the output port)
- ;------------------------------------------------------------------------
- ; Input: al = character (or byte) to output
- ; Output: none
- ; Registers: none
- ;------------------------------------------------------------------------
- PROC AsynchOut
- push dx
- push ax
- @@10:
- mov dx, LineStatus
- in al,dx
- and al,020h
- jz @@10
- pop ax
- mov dx, TxRegister
- out dx,al
- pop dx
- ret
- ENDP AsynchOut
-
- %NEWPAGE
- ;------------------------------------------------------------------------
- ; AsynchIn - input a byte (from buffer)
- ;------------------------------------------------------------------------
- ; Input: none
- ; Output: al = char from buffer
- ; NOTE: if buffer is empty, al will be 0, with
- ; no indication that this is not an input value.
- ; Precede with call to AsynchInStat to avoid reads
- ; from an empty buffer.
- ; Registers: al,bx
- ;------------------------------------------------------------------------
- PROC AsynchIn
- xor al,al
- mov bx,[bufTail]
- cmp bx,[bufHead]
- je @@99
- mov al,[byte ptr bx]
- inc [bufTail]
- cmp [word ptr bufTail], offset buffer + BufSize
- jb @@99
- mov [bufTail], offset buffer
- @@99:
- ret
- ENDP AsynchIn
-
- %NEWPAGE
- ;------------------------------------------------------------------------
- ; AsynchInStat - get status of input buffer
- ;------------------------------------------------------------------------
- ; Input: none
- ; Output: dx = number of bytes (or chars) in buffer
- ; Registers: dx
- ;------------------------------------------------------------------------
- PROC AsynchInStat
- mov dx,[bufHead]
- sub dx,[bufTail]
- jge @@99
- add dx,BufSize
- @@99:
- ret
- ENDP AsynchInStat
-
- %NEWPAGE
- ;------------------------------------------------------------------------
- ; AsynchISR - asynchronous input Interrupt Service Routine (ISR)
- ;------------------------------------------------------------------------
- ; Input: none
- ; Output: none (char read and deposited in buffer)
- ; NOTE: this version ignores buffer overflows
- ; Registers: none
- ;------------------------------------------------------------------------
- PROC AsynchISR
- push ax
- push bx
- push ds
- push dx
- mov ax,@data
- mov ds,ax
- mov dx,RxRegister
- in al,dx
- mov bx,[bufHead]
- mov [byte ptr bx], al
- inc bx
- cmp bx,offset buffer + BufSize
- jb @@10
- mov bx, offset buffer
- @@10:
- cmp bx,[bufTail]
- jne @@20
- mov bx,[bufHead]
- @@20:
- mov [bufHead],bx
- mov al,EOI
- out Ctrl8259_0,al
- pop dx
- pop ds
- pop bx
- pop ax
- iret
- ENDP AsynchISR
-
- END